package com.sneakxy.mybase4j.platform.controller;

import static java.lang.String.format;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileItemHeaders;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadBase.FileUploadIOException;
import org.apache.commons.fileupload.FileUploadBase.IOFileUploadException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.csource.common.MyException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sneakxy.mybase4j.base.MyBase4jCommonsMultipartResolver;
import com.sneakxy.mybase4j.base.controller.BaseController;
import com.sneakxy.mybase4j.platform.beans.UEditor;
import com.sneakxy.mybase4j.platform.service.IUEditorService;
import com.sneakxy.mybase4j.shiro.bean.ShiroAccount;

@RestController
@RequestMapping(
	value="/editor/ueditor"
)
public class UEditorController extends BaseController {
	
	@Resource
	private IUEditorService uEditorService;
	
	@Resource
	private MyBase4jCommonsMultipartResolver multipartResolver;
	
	@RequestMapping(params="action=config")
	public Object config(HttpServletRequest request, HttpServletResponse response, String callback) throws IOException {
		File config = new ClassPathResource("config.json").getFile();
		JSONObject json = (JSONObject) JSON.parse(FileUtils.readFileToString(config, "UTF-8"));
		String imageUrlPrefix = this.getFullPath(request, "/editor/ueditor/image/");
		String fileUrlPrefix = this.getFullPath(request, "/editor/ueditor/file/");
		if(!json.containsKey("imageUrlPrefix")) {
			json.put("imageUrlPrefix", imageUrlPrefix);
		}
		if(!json.containsKey("imageManagerUrlPrefix")) {
			json.put("imageManagerUrlPrefix", imageUrlPrefix);
		}
		if(!json.containsKey("scrawlUrlPrefix")) {
			json.put("scrawlUrlPrefix", imageUrlPrefix);
		}
		if(!json.containsKey("snapscreenUrlPrefix")) {
			json.put("snapscreenUrlPrefix", imageUrlPrefix);
		}
		if(!json.containsKey("catcherUrlPrefix")) {
			json.put("catcherUrlPrefix", imageUrlPrefix);
		}
		if(!json.containsKey("videoUrlPrefix")) {
			json.put("videoUrlPrefix", this.getFullPath(request, "/editor/ueditor/video/"));
		}
		if(!json.containsKey("fileUrlPrefix")) {
			json.put("fileUrlPrefix", fileUrlPrefix);
		}
		if(!json.containsKey("fileManagerUrlPrefix")) {
			json.put("fileManagerUrlPrefix", fileUrlPrefix);
		}
		return this.response(response, json, callback);
	}
	
	@RequestMapping(params="action=image")
	public Object image(HttpServletRequest request, HttpServletResponse response, String callback, MultipartFile file) throws IOException, MyException {
		UEditor ueditor = uEditorService.uploadAndSave(request, file, UEditor.TYPE_IMAGE);
		return this.response(response, ueditor.toMap(), callback);
	}
	
	@RequestMapping(params="action=snapscreen")
	public Object snapscreen(HttpServletRequest request, HttpServletResponse response, String callback) throws IOException, MyException {
		FileItemStream fileStream = null;
		FileItem fileItem = null;
		String originFileName = null;
		if (!(ServletFileUpload.isMultipartContent(request))) {
			
		}
		ServletFileUpload upload = multipartResolver.getServletFileUpload(request);
		try {
			FileItemIterator iterator = upload.getItemIterator(request);
			FileItemFactory factory = upload.getFileItemFactory();
			while (iterator.hasNext()) {
				fileStream = iterator.next();
				originFileName = fileStream.getName();
				fileItem = factory.createItem(fileStream.getFieldName(), fileStream.getContentType(),
						fileStream.isFormField(), originFileName);
				if (!(fileStream.isFormField()))
					break;
				fileStream = null;
				fileItem = null;
			}
			try {
                Streams.copy(fileStream.openStream(), fileItem.getOutputStream(), true);
            } catch (FileUploadIOException e) {
                throw (FileUploadException) e.getCause();
            } catch (IOException e) {
                throw new IOFileUploadException(format("Processing of %s request failed. %s",
                		FileUploadBase.MULTIPART_FORM_DATA, e.getMessage()), e);
            }
            final FileItemHeaders fih = fileStream.getHeaders();
            fileItem.setHeaders(fih);
            
            UEditor ueditor = this.uEditorService.uploadAndSave(request, new CommonsMultipartFile(fileItem), UEditor.TYPE_IMAGE);
            return this.response(response, ueditor.toMap(), callback);
		} catch (FileUploadException e) {

		} catch (IOException localIOException) {

		}
		return "{\r\n" + 
				"    \"state\": \"SUCCESS\",\r\n" + 
				"    \"url\": \"upload/demo.jpg\",\r\n" + 
				"    \"title\": \"demo.jpg\",\r\n" + 
				"    \"original\": \"demo.jpg\"\r\n" + 
				"}";
	}
	
	@RequestMapping(params="action=scrawl")
	public Object scrawl(HttpServletRequest request, HttpServletResponse response, String callback, String source) throws IOException, MyException {
		String filename = String.format("scrawl%s.jpg", DateFormatUtils.format(Calendar.getInstance(), "yyyyMMddHHmmss"));
		UEditor ueditor = uEditorService.uploadAndSave(request, source, filename);
		return this.response(response, ueditor.toMap(), callback);
	}
	
	@RequestMapping(params="action=catchimage")
	public Object catchimage(HttpServletResponse response, String callback, String[] source) throws IOException, MyException {
		throw new UnsupportedOperationException("图片搜索已经失效（百度不提供了），无法远程抓取图片");
	}
	
	@RequestMapping(params="action=video")
	public Object video(HttpServletRequest request, HttpServletResponse response, String callback, MultipartFile file) throws IOException, MyException {
		UEditor ueditor = uEditorService.uploadAndSave(request, file, UEditor.TYPE_VIDEO);
		return this.response(response, ueditor.toMap(), callback);
	}
	
	@RequestMapping(params="action=file")
	public Object file(HttpServletRequest request, HttpServletResponse response, String callback, MultipartFile file) throws IOException, MyException {
		UEditor ueditor = uEditorService.uploadAndSave(request, file, UEditor.TYPE_FILE);
		return this.response(response, ueditor.toMap(), callback);
	}
	
	@RequestMapping(params="action=listimage")
	public Object listimage(HttpServletResponse response, int start, int size, String callback) throws IOException, MyException {
		ShiroAccount account = this.getLoginAccount();
		Map<String, Object> result = this.uEditorService.findAll(UEditor.TYPE_IMAGE, account != null ? account.getAccount() : null, start, size);
		return this.response(response, result, callback);
	}
	
	@RequestMapping(params="action=listfile")
	public Object listfile(HttpServletResponse response, int start, int size, String callback) throws IOException, MyException {
		ShiroAccount account = this.getLoginAccount();
		Map<String, Object> result = this.uEditorService.findAll(UEditor.TYPE_FILE, account != null ? account.getAccount() : null, start, size);
		return this.response(response, result, callback);
	}
	
	public String getFullPath(HttpServletRequest request, String path) {
		return new StringBuilder()
				.append(request.getScheme())
				.append("://")
				.append(request.getServerName())
				.append(":")
				.append(request.getServerPort())
				.append(request.getContextPath())
				.append(path).toString();
	}
	
	public Object response(HttpServletResponse response, Object obj, String callback) {
		if(!StringUtils.isNotBlank(callback)) {
			return obj;
		}
		StringBuilder builder = new StringBuilder();
		builder.append(callback).append("(");
		builder.append(JSON.toJSONString(obj));
		builder.append(")");
		return builder.toString();
	}
	
}
